function getReady(array, func) {
    for (var i = 0; i < array.length; i++) {
        if (array[i].ready) {
            return func(array[i]);
        }
    }
    return null;
}

/**
 * SpriteResource.
 */
var SpriteResource = Class.create(Sprite, {
    initialize: function(w, h) {
        Sprite.call(this, w, h);
        this.ready = true;
        this.padX = 0;
        this.padY = 0;
    }
});

/**
 * Rail Gun.
 *
 * Basic Weapon.
 */
var RailGun = Class.create(SpriteResource, {
    initialize: function() {
        SpriteResource.call(this, 30, 1);
        this.backgroundColor = "#ccf";
        this.addEventListener("enterframe", function(e) {
            if (this.ready) return;
            if (!this.parentNode) return;
            
            for (var i = 0; i < this.width; i++) {
                if (Dtype.map.hitTest(this.x + i - Dtype.map.x, this.y)) {
                    this.ready = true;
                    this.parentNode.removeChild(this);
                    return;
                }
            }
            for (var i = 0; i < Dtype.enemies.length; i++) {
                var enemy = Dtype.enemies[i];
                
                if (enemy.ready == false && (this.intersect(enemy) || this.within(enemy, enemy.hitSize))) {
                    this.ready = true;
                    this.parentNode.removeChild(this);
                    enemy.damage(1);
                }
            }
            this.x += this.width;
            if (Dtype.game.width < this.x) {
                this.ready = true;
                this.parentNode.removeChild(this);
            }
        });
    }
});

/**
 * Enemy.
 */
var Enemy = Class.create(SpriteResource, {
    initialize: function() {
        SpriteResource.call(this, 32, 32);
        this.image = Dtype.game.assets["chara1.gif"];
        this.data = null;
        this.explosion = new Sprite(64, 64);
        this.explosion.image = Dtype.game.assets["explosion1.png"];
        this.explosion.addEventListener("enterframe", function(e) {
            if (!this.parentNode) return;
            console.log("explosion enterframe");
            this.frame += 1;
            if (15 <= this.frame) {
                this.parentNode.removeChild(this);
            }
        });
    },
    init: function(x, y, data) {
        this.data = data ? data : {};

        // default values begin
        this.width = 32;
        this.height = 32;
        this.hp = 1;
        this.hitSize = 10;
        this.scaleX = -1;
        this.scaleY = 1;
        this.frame = 0;
        // default values end

        if (this.data.oncreate) this.data.oncreate.call(this);
        this.x = x;
        this.y = y;
        this.ready = false;
        if (this.data.onenterframe) this.addEventListener("enterframe", this.data.onenterframe);
        Dtype.stage.addChild(this);
    },
    damage: function(dmg) {
        this.hp -= dmg;
        if (!this.hp || this.hp <= 0) {
            this.explode();
            Dtype.game.score += 100;
            console.log("kill");
            this.destroy();
        }
    },
    destroy: function() {
        this.parentNode.removeChild(this);
        if (this.data.onenterframe) this.removeEventListener("enterframe", this.data.onenterframe);
        if (this.data.ondestroy) this.data.ondestroy.call(this);
        if (this.parentNode) this.parentNode.removeChild(this);
        this.ready = true;
        this.data = null;
    },
    explode: function() {
        try {
//            Dtype.sound.explode.stop();
//            Dtype.sound.explode.play();
        } catch (e) {}
        
        this.explosion.scaleX = this.hitSize / 10;
        this.explosion.scaleY = this.hitSize / 10;
        this.explosion.frame = 0;
        this.explosion.x = this.x + this.width / 2 - this.explosion.width / 2;
        this.explosion.y = this.y + this.height / 2 - this.explosion.height / 2;

        this.parentNode.addChild(this.explosion);
    }
});

/**
 * Enemy Bullet.
 */
var EnemyBullet = Class.create(SpriteResource, {
    initialize: function() {
        SpriteResource.call(this, 3, 3);
        this.backgroundColor = "#fc9";
        this.addEventListener("enterframe", function(e) {
            this.x += Math.cos(this.d) * this.speed;
            this.y += Math.sin(this.d) * this.speed;
            if (this.x < 0 || Dtype.game.width < this.x || this.y < 0 || Dtype.game.height < this.y) {
                this.destroy();
                return;
            }
            if (Dtype.map.hitTest(this.x - Dtype.map.x, this.y)) {
                this.destroy();
                return;
            }
            if (this.within(Dtype.myFighter, Dtype.myFighter.hitSize)) {
                this.destroy();
                Dtype.myFighter.miss();
            }
        });
    },
    init: function(x, y, target) {
        this.x = x;
        this.y = y;
        this.speed = 6;
        var dx = target.x + (target.width ? target.width : 0) / 2;
        var dy = target.y + (target.height ? target.height : 0) / 2;
        if (dx == this.x) {
            if (dy < this.y) {
                this.d = Math.PI / -2;
            } else {
                this.d = Math.PI / 2;
            }
        } else {
            this.d = Math.atan((dy - this.y) / (dx - this.x));
        }
        if (dx < this.x) {
            this.d += Math.PI;
        }
        this.ready = false;
        Dtype.stage.addChild(this);
    },
    init2: function(x, y, r) {
        this.init(x, y, { x: Math.cos(r) * 320, y: Math.sin(r) * 320 });
    },
    destroy: function() {
        if (this.parentNode) {
            this.parentNode.removeChild(this);
        }
        this.ready = true;
    }
});